package com.example.dynamicjavacode;

import com.example.dynamicjavacode.util.ApplicationUtil;
import com.example.dynamicjavacode.util.DynamicClassLoader;
import com.example.dynamicjavacode.util.DynamicCompiler;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.lang.reflect.Method;

@SpringBootApplication
@Controller
public class DynamicJavaCodeApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(DynamicJavaCodeApplication.class, args);
        ApplicationUtil.applicationContext = run;
        DynamicCompiler.init();
    }


    /**
     * 测试接口，实际上就是完成动态编译java源码、加载字节码变成Class，装载Class到spring容器，
     * 获取对象，调用对象的测试
     *
     * @return
     * @throws Exception
     */
    @RequestMapping("/test")
    @ResponseBody
    public String test() throws Exception {
        String code = new String("package com.test;\n" +
                "\n" +
                "import org.springframework.beans.factory.annotation.Autowired;\n" +
                "import org.springframework.stereotype.Component;\n" +
                "import com.example.dynamicjavacode.test.TestComponent;\n" +
                "\n" +
                "@Component\n" +
                "public class T5 {\n" +
                "    @Autowired\n" +
                "    private TestComponent testComponent;\n" +
                "\n" +
                "    void print(String a) {\n" +
                "        testComponent.print();\n" +
                "        System.out.println(\"Hello world! \" + a);\n" +
                "    }\n" +
                "\n" +
                "    static void print(Integer b, String a) {\n" +
                "        System.out.println(\"Hello world! \" + b + a);\n" +
                "    }\n" +
                "}");
        /*Class<?> load = DynamicClassLoader.load(code);
        // 4、传入方法所需的参数通过invoke运行方法
        Method method = load.getDeclaredMethod("print", String.class);
        method.setAccessible(true);
        method.invoke(null, "123"); //当类型为String[]时，需要(Object)new String[] {}初始化*/
        ApplicationUtil.register("T5", code);
        Object t5 = ApplicationUtil.getBean("T5");
        Class<?> aClass = t5.getClass();
        Method method = aClass.getDeclaredMethod("print", String.class);
        method.setAccessible(true);
        method.invoke(t5, "123"); //当类型为String[]时，需要(Object)new String[] {}初始化*/
        return "true";
    }

}
